查看原文
其他

追求极限性能的芯片设计方法(四)

2017-06-14 吴臻志,李晓阳 StarryHeavensAbove

前情提示

虽然前文已经阐述了,对于一个数字电路系统而言,效率e是提升系统能效的最主要参量。遵循极限量化设计,我们可以期望得到一个理想的e=1的系统。然而实际上我们总会遇到各种不理想的情况,使得效率没有想象的那么高。未达到满效率源于多种因素,主要包括数据原因类、控制原因类、传输原因类、算法和配置原因类、灵活度原因类。以下将分别阐述,并最后给出一个设计检查表格,用于检查一个系统是否具有效率损失,以及可能的解决方法。


这一部分将介绍未达到最优性能的原因排查与分析

     

[ 1 ] 数据原因类

数据无法在指定时序下到达运算单元,或无法在指定时序下输出(输入堵,输出堵)

具体地,包括以下可能的原因:

情形1. 计算性能与存储带宽的不匹配,也称为存储墙(memory access bottleneck)。比如具有N(N>1)路运算单元,但只有一路存储器/寄存器写回接口(尤其是访问片外内存时),或存储调用占用了多于一个时钟周期。造成了计算快于存储读写的情形。在这种情况下首先可以考虑通过层次化的内存结构降低带宽长延迟的存储访问,在局部通过寄存器堆,Mutli-bank Scratch-pad memory,让绝大多数操作在高带宽的局域内完成,全局远程数据交换尽量少。对于大存储需求的设计,在有时间重用/位置重用的情形下,采用层次化多级内存(cache)结构也可以显著减小内存访问代价。

 对于大内存需求的系统,尽量采用Tiling机制压缩局域内存尺寸,即内存划片。它的概念是每段时间,运算单元只需要一个区域的内存数据,或者可以将这些数据整理到一个区域,那么就将这部分数据调入到片内即可。这个区域的大小可以用重用距离表示。如果重用距离超出缓冲区尺度,那么就需要外存的访问,这时候效率就难以保证了。因此,恰当的内存Tiling和缓冲区大小选择,对于效率影响很大。

 

情形2. 计算性能与输入输出/路由效率的不匹配

由于有些计算的数据来源和数据归宿需要通过输入输出接口、片内/片间路由、总线等传输,因此输入输出接口带宽不足会影响计算效率。例如2D Mesh路由在某时间内的交通拥堵,总线上并发传输的数据包过多等。其解决办法包括如下几方面:(1).软件层面更好的规划,若干模块之间分时错开高峰,确保在计算所需要的时间窗内输入输出带宽足够大;(2).更大的缓冲区,用以缓冲局部时间压力造成的数据传输失效,当然对于不可预测的数据访问未必有意义;(3).更规则的访问,例如按片读写,而不是随机读写,可以有效降低路由开销。

 

情形3. 数据的时间依赖

由于计算B的数据源中包含了计算A的结果,而计算A还没有完成,从而造成了计算B无法进行。在数据依赖层面,Data flow graph可以帮助用户整理程序或算法中的数据依赖关系,构建一个依赖草图。保证关键路径优先被处理,甚至从算法层面打破关键链,牺牲微小性能换取并行。然而这还不够,流水线的处理模式导致即使没有运算级别的依赖,流水线内的数据依赖也会经常发生。在流水线结构下,运算之间的相对流水级会产生相应的“读后写”冲突。即数据读取的流水级早于它形成的流水级,此时必须填充无操作(NOP)保证流水的工作时序,某些时序节拍下运算单元无法填满运算任务,导致计算单元的闲置,从而造成了效率损失。因此一个数字逻辑设计反复优化的是流水编排。在硬件设计中,主要通过增加前推网络(即输出结果不写回存储器,直接供给到其他流水级)。另一个方法是调整运算顺序。例如在处理器设计中,这部分任务是由编译器或乱序发射的硬件模块完成的,在加速器设计中,需要设计者手工设计优化,处理器的汇编语言开发者也在一定程度上采用手工优化流水编排的方法以提升处理器的运行效率。另外,这在块数据和流数据混合的系统中非常严重。需要妥善编排块处理部分和流处理部分(例如FFT,前后向迭代算法)。采用缓冲部分数据的方法处理数据依赖。

 

情形4. 数据的空间依赖(shuffling)

在空间上,多个计算单元的并行计算使得数据的交叉互换变得非常复杂。对于并行计算单元而言,输出数据的位置未必是输入的位置(原位),因此并行置换网络成为必需的要素。一些一一映射网络,例如2N-point FFT,Trellis Graph,3GPP-LTETurbo并行交织器(QPP 交织器),QC-LDPC的循环移位存储,单层全连接神经网络都是规则地址访问的情形,而稀疏神经网络,HSPA Turbo并行交织器等存在一对多或者多对一的映射,属于非规则地址访问的情形。前者由于访问模式较为规则,一般可以做到无冲突并行。而后者往往需要更多的努力,例如采用fully crossbar,butterfly,2D-mesh router等并行置换网络以及多FIFO缓冲机制达到近似无冲突的并行。往往一个置换网络需要多个周期完成数据的置换,这也大大增加了流水线的排布难度。造成了效率的降低。因此并行计算系统的核心技术之一是复杂互联网络下的并行数据置换问题。本系列文章将在今后讨论可预测存取系统中的无冲突内存存取技术,以及不可预测存取系统的路由策略。

 

情形5. 模块间的工作协调关系

对于很多流式数据处理(例如通信基带数据流,神经网络计算的视频输入流),前继模块的输出是当前模块的输入,因此只有前继模块的数据到达了,当前时序的运算才可以开始。否则需要等待输入数据。计算的结果需要输出到后继模块,如果后继模块无法接收,那么当前模块的计算过程也只能暂停。解决方法是更好的通过“折叠-打开”逻辑配平各个模块的并行度关系,另外可以增大模块间缓冲区缓冲突发数据。

 

情形6. 扇入扇出问题

经常地,计算单元具有不等价的扇入扇出,例如多个数据的求和形成的倒三角结构,有N个输入和1个输出。此时如果希望同时提供N个扇入,那么扇入带宽就会非常大,扇入扇出比例为N/1。而如果此部分加法电路还用于计算M路变量各自的累加,这时有M路输入,M路输出,扇入扇出比例为M/M=1,因此虽然计算单元没有变,但是扇入扇出形成了瓶颈,造成供应数据带宽不足,数据通路不饱和。解决方法是采用多时钟的分时输入/输出,配合寄存器阵列(串入并出)缓冲的机制。

 

情形7. 输入输出端口竞争

如多个模块竞争一条总线或者一个内存接口,一个外部设备等等。造成计算停顿。在模块内部,例如ALU执行的add指令的结果,MAC执行的乘加的结果,load读取外部data memory的结果都希望同时存入Register file,造成写端口冲突,造成写阻塞。有时,可以通过软件优化将这种情形规避或减少。也可以通过硬件仲裁机制解决。但这都造成了性能损失。

 

除了上述典型情况之外,还有很多其它因素,例如模块间工作协调问题;数据传输延迟不可控或过长;计算流水中组合逻辑长短不一致;核心器件结构不优化等情况,会使得设计出的架构没有别人做出的架构效率高。


[ 2 ] 控制原因类


情形8. 控制原因

控制逻辑无法在指定时序下提供控制逻辑,导致运算或内存模块暂停工作。由于控制逻辑是电路的所有多路选择器,使能信号和内存地址信息的源头。如果控制逻辑无法按时更新,整个运作流程就会失控,从而执行单元不得不等待控制逻辑能够提供正确的控制信息后才可继续工作。

最典型的例子就是循环。如果采用软件实现循环,那么在进行循环边界条件判断和跳转的过程,其他并行数据计算任务必须暂停。因此高性能DSP往往具有硬件化的循环加速器,简单的就是采用若干可配置的计数器实现等效的循环控制。循环还可以通过loop unrolling技术缓解,即将一部分循环展开成顺序代码,这样就不需要过多的进行边界判断。

另外一个典型例子是条件跳转,往往会造成流水线下的控制相关冲突。即当条件跳转判别计算出来的时候,后期的若干指令已经进入到流水线中,而这些指令处于未跳转的路径上,本是不应该被执行的。在硬件上通过流水线冲刷的办法规避了冲突,采用分支预测技术可优化跳转效率,也可以采用分支延迟槽技术,即明确规定跳转后的若干条执行也是需要被无条件执行的,之后通过编译器的优化来提升效率。

另外,最严重的一部分效率损失发生在内存的地址计算上,如果采用软件计算的方法,那么很多时间都用在地址计算而不是数据的计算了。解决的办法中,最好的是采用硬件地址生成器,然而这个需要在芯片设计时就将这种地址变化模式设计进去,对于其他无法预计的模式,可以通过查找表的方法,将地址保存成表格。尤其在并行系统中的并行内存访问的地址问题,由于地址可能是被“计算”出来的,地址计算不够快,就无法按时取得数据。因此硬件化的地址生成器对于提高效率非常重要。有些时候,内存访问地址需要等待计算结果产生后才能决定,也称为数据依赖的寻址,我们尽量避免这种情况。


[ 3 ] 传输原因类


情形9. 数据通信导致的时间开销

在多个模块间,需要传输数据,数据通信(路由或总线)传输往往无法与计算完全并行,导致额外的数据通信时间。因此传输开销越短,效率越高。而传输开销(时间开销)与路由拓扑结构、路由策略,通信协议等都有关系。最简单的处理原则是尽量限制传输距离,能在片内传输的不要跨芯片,能在板级传输的不要跨板,甚至不传输(通过内存片互换的方法)。选择更适合的路由或总线。这些问题需要采用一个专题阐述。另外,当多核系统数据互传输时,往往需要进行数据同步,即所有路由都传输完毕,才能进入下一个计算环节。例如多线程的同步,多核的同步,系统级同步,有些节点可能已经完成了计算,而另外一些节点还在计算,根据木桶效应,耗时最长的节点的工作节拍是最快的同步节拍,对于完成计算的节点而言,就造成了效率损失。解决的方法包括数据流驱动模式,带时间戳的数据传输模式使得多个计算环节可以混合工作等。

另一种情况是,数据传输过多依赖于处理器的支持,处理器不得不花很多时间或很多中断来处理数据。因此有效的处理方法是采用其它模块例如内存管理模块(如DMA)、Cache管理、总线等而不通过处理器进行内存调度。


[ 4 ] 算法和配置原因类


情形10. 算法不够优化

最常见的情况是采用了硬件不友好或者代价高的算法,例如留有复杂运算、并行度不高、数据依赖关系复杂、内存访问不规则、无意义的内存访问等,导致相同目的下的硬件代价高;量化做的不好会导致数据通路过宽,此时应尝试降低数据通路带宽。另外,专用硬件的主要特点是内存并行存取。算法如果无法充分利用这个特点,其数据访问效率就无法发挥出来。另外,并行处理的特点是,一旦电路设计好之后,并行度就是无法修改的。而算法没能够充分利用所有时间(时钟)下的并行资源,就造成了效率损失。

 

情形11. 初始化造成的时间开销

初始化开销包括内存初始化开销和配置参数初始化开销。其中内存初始化主要是因为算法需要对内存进行刷全0处理,而内存本身没有这种复位能力,需要逐个刷0。解决办法之一是采用标注+多路选择法,即做一个标志位,第一次运算时,标志位为1,数据源不从内存读入,而是直接置0。当不是第一次运算时,标志位清0,从而从内存取数据。另一个办法是采用寄存器阵列实现。如果存储容量很小的情况下。对于参数初始化造成的开销,往往是因为参数需要从片外(Flash,硬盘)调入,且这个调入接口是串行低速的。可以通过压缩传输的方法降低传输代价。另外可以先配置部分初始化数据,让一部分运算开始进行,在此时继续初始化剩余的数据。另外,也可以在片内集成非易失存储器或存储器阵列,从而降低存储器访问延迟,拓宽初始化存储器带宽。


[ 5 ] 灵活度原因类


情形12. 多模结构造成的效率损失

经常的,一个电路模块往往要支持多个工作模式共享内存、控制单元和数据通路,在某些工作模式下,其优化必须在某个通用框架下进行,因此构成了计算单元无法饱和运转,造成效率损失。因此多模硬件的设计要适当的进行模块划分,让各个模块的带宽,存储容量都基本统一,时序上对原独立工作模式而言冗余度不大,才是一个优秀的多模融合设计。

 

综上,我们已经阐述了效率损失的种种原因。综合起来,可以将各种原因及其对策整理成一个表格,如表1所述。


表1. 效率不足原因的检查列表


总  结

这一部分阐述了效率未达到最佳效率的可能原因。芯片设计者应早期进行检查和规避。对于一个硬件设计,优秀的和不优秀的,可能具有一个数量级的性能差别。其可优化的空间可以通过效率e以及算法的特点初步确定。当然,最好的办法是通过高层建模的方法验证功能和性能。


作者简介

吴臻志博士,清华大学类脑计算研究中心助理研究员。专长通信基带专用处理器和信道译码加速器设计,神经网络和神经形态芯片设计。邮件:wuzhenzhi@gmail.com

同行及朋友可加微信:zhenzhi-wu


李晓阳,北京兆芯高级工程师,从事异构计算与加速器设计。

邮件:alexli@zhaoxin.com


题图来自网络,版权归原作者所有

推荐阅读  

追求极限性能的芯片设计方法(一)

追求极限性能的芯片设计方法(二)

追求极限性能的芯片设计方法(三)

AI芯片架构的争论真有意义吗?

专用处理器设计方法&工具

从Nvidia开源深度学习加速器说起

Nvidia Volta - 架构看点

AI会给芯片设计带来什么?

如何做神经网络处理器的需求分析?

深度神经网络的模型·硬件联合优化

脉动阵列 - 因Google TPU获得新生

长按二维码关注

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存